Subcommand Groups
You read before how to create a program with Commands.
Now we'll see how to create a CLI program with commands that have their own subcommands. Also known as command groups.
Add Typer
举个例子,现在有两个命令程序 items.py 和 user.py 分别有两个子命令 create 和 delete,如何把他们组合起来呢?
import typer
import items
import users
app = typer.Typer()
app.add_typer(users.app, name="users")
app.add_typer(items.app, name="items")
if __name__ == "__main__":
app()


你甚至可以一直套娃下去。Do you need sub-sub-sub-subcommands? Go ahead, create all the
typer.Typer()
s you need and put them together withapp.add_typer()
.Typer applications are composable, each
typer.Typer()
can be a CLI app by itself, but it can also be added as a command group to another Typer app.
SubCommands in a Single File
如果必须这么做的话,你也可以在一个文件里定义一堆子命令组……不过不推荐就是了
import typer
app = typer.Typer()
items_app = typer.Typer()
app.add_typer(items_app, name="items")
users_app = typer.Typer()
app.add_typer(users_app, name="users")
@items_app.command("create")
def items_create(item: str):
print(f"Creating item: {item}")
@items_app.command("delete")
def items_delete(item: str):
print(f"Deleting item: {item}")
@items_app.command("sell")
def items_sell(item: str):
print(f"Selling item: {item}")
@users_app.command("create")
def users_create(user_name: str):
print(f"Creating user: {user_name}")
@users_app.command("delete")
def users_delete(user_name: str):
print(f"Deleting user: {user_name}")
if __name__ == "__main__":
app()
Sub Callback
子命令也能拥有属于自己的 callback!
It can handle any CLI parameters that go before its own commands and execute any extra code:
import typer
app = typer.Typer()
users_app = typer.Typer()
app.add_typer(users_app, name="users")
@users_app.callback()
def users_callback():
print("Running a users command")
@users_app.command()
def create(name: str):
print(f"Creating user: {name}")
if __name__ == "__main__":
app()
In this case it doesn't define any CLI parameters, it just writes a message.
当然也可以在实例化 typer.Typer
的时候填 callback 进去,it's just another place to add the callback.
def users_callback():
print("Running a users command")
users_app = typer.Typer(callback=users_callback)
app.add_typer(users_app, name="users")
甚至,你可以在 app.add_typer()
的时候写 callback
def callback_for_add_typer():
print("I have the high land! Running users command")
app.add_typer(users_app, name="users", callback=callback_for_add_typer)
优先级从高到低:
app.add_typer(callback)
@users_app.callback()
typer.Typer(callback=users_callback)
help
可以在 app.add_typer
的时候写入注释说明
app = typer.Typer()
users_app = typer.Typer()
app.add_typer(users_app, name="users", help="Manage users in the app.")

当然在其他地方也可以写入注释说明,他们的优先级和 callback 是一样的:
app.add_typer(help)
app.add_typer(callback=some_function)
@sub_app.callback()
sub_app = typer.Typer(callback=some_function)
Recap
The precedence to generate a command's name and help, from lowest priority to highest, is:
- Implicitly inferred from
sub_app = typer.Typer(callback=some_function)
- Implicitly inferred from the callback function under
@sub_app.callback()
- Implicitly inferred from
app.add_typer(sub_app, callback=some_function)
- Explicitly set on
sub_app = typer.Typer(name="some-name", help="Some help.")
- Explicitly set on
@sub_app.callback("some-name", help="Some help.")
- Explicitly set on
app.add_typer(sub_app, name="some-name", help="Some help.")
So, app.add_typer(sub_app, name="some-name", help="Some help.")
always wins.